package com.guldan.jaina.manager;

import java.util.*;
import java.util.concurrent.LinkedBlockingQueue;

import com.guldan.core.constants.XlsHeaderConstant;
import com.guldan.core.utils.MathUtil;
import com.guldan.jaina.dto.household.HouseholdDTO;
import com.guldan.jaina.dto.progress.BarDTO;
import com.guldan.jaina.utils.ComUtils;
import com.guldan.mapper.db.entity.*;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.guldan.core.constants.CommonConstant;
import com.guldan.core.enums.CitizenValidatingTypeEn;
import com.guldan.core.exception.BusinessException;
import com.guldan.core.manager.BaseManager;
import com.guldan.core.search.Pagination;
import com.guldan.core.utils.DateUtil;
import com.guldan.jaina.dto.area.AreaDTO;
import com.guldan.jaina.dto.area.AreaSearchDTO;
import com.guldan.jaina.dto.citizenbank.CitizenBankDTO;
import com.guldan.jaina.dto.citizenfail.CitizenFailDTO;
import com.guldan.jaina.dto.citizeninfo.CitizenInfoDTO;
import com.guldan.jaina.dto.citizeninfo.CitizenInfoSearchDTO;
import com.guldan.jaina.dto.citizenproperty.CitizenPropertyDTO;
import com.guldan.jaina.dto.dictionary.DictionaryDTO;
import com.guldan.jaina.dto.dictionary.DictionarySearchDTO;
import com.guldan.jaina.utils.CitizenInfoDomainConvertUtils;
import com.guldan.jaina.utils.UserUtils;
import com.guldan.jaina.utils.validating.CheckIdCard;
import com.guldan.mapper.db.mapper.AreaMapperExt;
import com.guldan.mapper.db.mapper.CitizenInfoMapperExt;
import com.guldan.mapper.db.mapper.HouseholdMapperExt;

/**
 * Created by Silas.
 * Date: 2016/11/7
 * Time: 22:55
 */
@Service
public class CitizenInfoManager extends BaseManager {

    @Autowired
    private CitizenInfoMapperExt citizenInfoMapperExt;

    @Autowired
    private CitizenPropertyManager citizenPropertyManager;

    @Autowired
    private CitizenBankManager citizenBankManager;

    @Autowired
    private HouseholdManager householdManager;

    @Autowired
    private HouseholdMapperExt householdMapperExt;

    @Autowired
    private AreaMapperExt areaMapperExt;

    @Autowired
    private AreaManager areaManager;

    @Autowired
    private CitizenFailManager citizenFailManager;

    @Autowired
    private DictionaryManager dictionaryManager;

    //获取单个居民信息
    public CitizenInfoDTO get(Integer citizenInfoId) {
        CitizenInfoDTO dto = CitizenInfoDomainConvertUtils.convert(citizenInfoMapperExt.selectByPrimaryKey(citizenInfoId));
        dto.setAreaName(areaMapperExt.selectByPrimaryKey(dto.getAreaId()).getAreaName());
        dto.setCitizenProperty(citizenPropertyManager.getByCitizenInfoId(citizenInfoId));
        dto.setCitizenBankList(citizenBankManager.getByCitizenInfoId(citizenInfoId));
        dto.setHousehold(householdManager.get(dto.getHouseholdId()));
        if (dto.getHousehold() != null && dto.getHousehold().getHouseholdId() != null)
            dto.setHouseholdRegisterNumber(dto.getHousehold().getHouseholdRegisterNumber());
        return dto;
    }


    //判断某个居民是否已经存在
    public Boolean checkExist(String identNumber) {
        CitizenInfoExample example = new CitizenInfoExample();
        CitizenInfoExample.Criteria criteria = example.createCriteria();
        criteria.andIdentNumberEqualTo(identNumber);
        criteria.andIsDeleteEqualTo(false);
        int count = citizenInfoMapperExt.countByExample(example);
        if (count > 0) {
            return true;
        } else {
            return false;
        }
    }

    //判断某个居民是否已经存在
    public CitizenInfoDTO checkExistAndReturnDTO(String identNumber) {
        CitizenInfoExample example = new CitizenInfoExample();
        CitizenInfoExample.Criteria criteria = example.createCriteria();
        criteria.andIdentNumberEqualTo(identNumber);
        criteria.andIsDeleteEqualTo(false);
        List<CitizenInfo> list = citizenInfoMapperExt.selectByExample(example);
        if (list != null && list.size() > 0) {
            CitizenInfoDTO dto = CitizenInfoDomainConvertUtils.convert(list.get(0));
            dto.setAreaName(areaMapperExt.selectByPrimaryKey(dto.getAreaId()).getAreaName());
            return dto;
        } else {
            return null;
        }
    }

    //新增/更新单个居民，传入：CitizenInfoDTO
    public CitizenInfoDTO save(CitizenInfoDTO dto, boolean needIdCheck) throws BusinessException {


        //校验身份证格式
        CheckIdCard cic = new CheckIdCard(dto.getIdentNumber());
        if (!cic.validate()) {
            throw new BusinessException("身份证格式错误");
        }

        //校验姓名格式，不能包含空格
        if (dto.getName().contains(" ")) {
            throw new BusinessException("姓名不能包含空格");
        }

        //检验卡号只能为数字
        if (dto.getCitizenBankList() != null && dto.getCitizenBankList().size() > 0) {
            for (CitizenBankDTO bankDTO : dto.getCitizenBankList()) {
                if (!MathUtil.isInteger(bankDTO.getBankNumber())) {
                    throw new BusinessException("卡号：" + bankDTO.getBankNumber() + "，卡号不能输入数字以外的值");
                }
            }
        }

        //校验户口簿编号只能为数字+字母
        if (dto.getHousehold() != null && dto.getHousehold().getHouseholdRegisterNumber() != null) {
            if (!MathUtil.isNumberAndChar(dto.getHousehold().getHouseholdRegisterNumber())) {
                throw new BusinessException("户口簿编号只能为数字+字母");
            }
        }

        //校验户主关系，户主身份证
        if (dto.getMaster()) {
            //是户主，则户主关系只能为“户主”
            if (!dto.getRelationCode().equals(CommonConstant.DIC_CODE_ISMASTER) || !dto.getHousehold().getHouseholdNumber().equals(dto.getIdentNumber())) {
                throw new BusinessException("如居民为户主，则与户主关系只能为‘户主’ 且 户主证件号需和身份证号一致");
            }

        } else {
            //则户主关系只能为户主之外的，且户主证件号码与本人证件号码不能相同；
            if (dto.getRelationCode().equals(CommonConstant.DIC_CODE_ISMASTER) || dto.getHousehold().getHouseholdNumber().equals(dto.getIdentNumber())) {
                throw new BusinessException("如居民不为户主，则与户主关系不能为‘户主’ 且 户主证件号不能和身份证号一致");
            }
            //户主证件号校验
            CheckIdCard cic2 = new CheckIdCard(dto.getHousehold().getHouseholdNumber());
            if (!cic2.validate() && needIdCheck) {
                throw new BusinessException("户主证件号格式不正确");
            }
        }


        //获取出生年月
        dto.setBirthday(DateUtil.toLocaleString(cic.getBirthDate()));
        //获取性别
        dto.setGenderCode(cic.getGenderCode() == 1 ? "100" : "101");
        //获取年龄
        dto.setAge(cic.getAge());


        CitizenInfo entity;

        if (dto.getCitizenInfoId() != null && dto.getCitizenInfoId() > 0) {

            //保存
            entity = citizenInfoMapperExt.selectByPrimaryKey(dto.getCitizenInfoId());

            //判断身份证是否存在
            if (!entity.getIdentNumber().equals(dto.getIdentNumber())) {
                if (checkExist(dto.getIdentNumber())) {
                    throw new BusinessException("身份证已存在");
                }
            }

            //判断银行卡号
            if (dto.getCitizenBankList() != null && dto.getCitizenBankList().size() > 0) {
                for (CitizenBankDTO citizenBankDTO : dto.getCitizenBankList()) {
                    CitizenBankDTO bankDTO = citizenBankManager.getByNumber(citizenBankDTO.getBankNumber());
                    if (bankDTO != null && bankDTO.getCitizenInfoId().intValue() != dto.getCitizenInfoId().intValue()) {
                        //获取银行名称
                        DictionaryDTO dictionaryDTO = (DictionaryDTO) cacheService.getCache(String.format(CommonConstant.KEY_DIC, CommonConstant.DIC_TYPE_BANKCODE, bankDTO.getBankCode()));
                        //logger.error(String.format("银行[%s]卡号[%s]已经存在", dictionaryDTO.getDictionaryName(), bankDTO.getBankNumber()));

                        CitizenInfoDTO ci = get(bankDTO.getCitizenInfoId());
                        throw new BusinessException(String.format("已经存在，银行[%s]卡号[%s]（归属：%s，%s）",
                                dictionaryDTO.getDictionaryName(),
                                bankDTO.getBankNumber(),
                                ci.getName(),
                                ci.getAreaName()
                        ));
                    } else {
                        //logger.error("gggggggggg");
                    }
                }
            }

            //保存居民家庭信息
            Integer householdId = null;
            if (dto.getHousehold() != null && StringUtils.isNotBlank(dto.getHousehold().getHouseholdRegisterNumber())) {
                if (dto.getHouseHoldTypeCode() != null)
                    dto.getHousehold().setHouseholdTypeCode(dto.getHouseHoldTypeCode());
                /*if (dto.getIdentNumber() != null)
                    dto.getHousehold().setHouseholdNumber(dto.getIdentNumber());
*/
                householdId = householdManager.save(dto.getHousehold()).getHouseholdId();
            }

            entity.setCitizenInfoId(dto.getCitizenInfoId());
            entity.setIdentTypeCode(dto.getIdentTypeCode());
            entity.setIdentNumber(dto.getIdentNumber());
            entity.setName(dto.getName());
            entity.setNameZw(dto.getNameZw());
            entity.setGenderCode(dto.getGenderCode());
            entity.setNationCode(dto.getNationCode());
            entity.setDegreeCode(dto.getDegreeCode());
            entity.setBirthday(DateUtil.parse(dto.getBirthday(), DateUtil.DEFAULT_DATE_FORMAT));
            entity.setAddress(dto.getAddress());
            entity.setAddressZw(dto.getAddressZw());
            entity.setTelephone(dto.getTelephone());
            entity.setAreaId(dto.getAreaId());
            entity.setCitizenInfoTypeCode(dto.getCitizenInfoTypeCode());
            entity.setHouseHoldTypeCode(dto.getHouseHoldTypeCode());
            entity.setIsMaster(dto.getMaster());
            entity.setRelationCode(dto.getRelationCode());
            entity.setHouseholdId(householdId);
            entity.setIsCheck(dto.getCheck());
            entity.setRemark(dto.getRemark());
            entity.setState(dto.getState());
            entity.setChecker(dto.getChecker());
            entity.setCheckDate(DateUtil.parse(dto.getCheckDate(), DateUtil.DEFAULT_DATE_FORMAT));
            entity.setAge(dto.getAge());
            entity.setModifyTime(DateUtil.getCurrentTime());
            entity.setModifier(dto.getModifier());

            //保存居民基本信息
            citizenInfoMapperExt.updateByPrimaryKeySelective(entity);
            //保存居民性质表
            dto.getCitizenProperty().setCitizenInfoId(entity.getCitizenInfoId());
            citizenPropertyManager.save(dto.getCitizenProperty());
            //保存居民银行卡信息
            citizenBankManager.saveList(dto.getCitizenInfoId(), dto.getCitizenBankList());

        } else {

            if (checkExist(dto.getIdentNumber())) {
                throw new BusinessException("身份证已存在");
            }

            //判断银行卡号是否已经存在
            if (dto.getCitizenBankList() != null && dto.getCitizenBankList().size() > 0) {
                for (CitizenBankDTO citizenBankDTO : dto.getCitizenBankList()) {
                    CitizenBankDTO bankDTO = citizenBankManager.getByNumber(citizenBankDTO.getBankNumber());
                    if (bankDTO != null) {
                        //获取银行名称
                        DictionaryDTO dictionaryDTO = (DictionaryDTO) cacheService.getCache(String.format(CommonConstant.KEY_DIC, CommonConstant.DIC_TYPE_BANKCODE, bankDTO.getBankCode()));

                        CitizenInfoDTO ci = get(bankDTO.getCitizenInfoId());
                        throw new BusinessException(String.format("已经存在，银行[%s]卡号[%s]（归属：%s，%s）",
                                dictionaryDTO.getDictionaryName(),
                                bankDTO.getBankNumber(),
                                ci.getName(),
                                ci.getAreaName()
                        ));
                    }
                }
            }


            //新增
            entity = new CitizenInfo();

            //保存居民家庭信息
            Integer householdId = null;
            if (dto.getHousehold() != null && StringUtils.isNotBlank(dto.getHousehold().getHouseholdRegisterNumber())) {
                householdId = householdManager.save(dto.getHousehold()).getHouseholdId();
            }

            entity.setCitizenInfoId(dto.getCitizenInfoId());
            entity.setIdentTypeCode(dto.getIdentTypeCode());
            entity.setIdentNumber(dto.getIdentNumber());
            entity.setName(dto.getName());
            entity.setNameZw(dto.getNameZw());
            entity.setGenderCode(dto.getGenderCode());
            entity.setNationCode(dto.getNationCode());
            entity.setDegreeCode(dto.getDegreeCode());
            entity.setBirthday(DateUtil.parse(dto.getBirthday(), DateUtil.DEFAULT_DATE_FORMAT));
            entity.setAddress(dto.getAddress());
            entity.setAddressZw(dto.getAddressZw());
            entity.setTelephone(dto.getTelephone());
            entity.setAreaId(dto.getAreaId());
            entity.setCitizenInfoTypeCode(dto.getCitizenInfoTypeCode());
            entity.setHouseHoldTypeCode(dto.getHouseHoldTypeCode());
            entity.setIsMaster(dto.getMaster());
            entity.setRelationCode(dto.getRelationCode());
            entity.setHouseholdId(householdId);
            entity.setIsCheck(dto.getCheck());
            entity.setRemark(dto.getRemark());
            entity.setState(dto.getState());
//            entity.setChecker(dto.getChecker());
//            entity.setCheckDate(DateUtil.parse(dto.getCheckDate(), DateUtil.YYYY_MM_DD));
            entity.setAge(dto.getAge());
            entity.setCreator(dto.getModifier());
            entity.setCreateTime(DateUtil.getCurrentTime());
            citizenInfoMapperExt.insertSelective(entity);

            //保存居民性质表
            dto.setCitizenInfoId(entity.getCitizenInfoId());
            if (dto.getCitizenProperty() == null) {
                CitizenPropertyDTO citizenPropertyDTO = new CitizenPropertyDTO();
                citizenPropertyDTO.setCitizenInfoId(entity.getCitizenInfoId());
                citizenPropertyDTO.setCreateTime(DateUtil.toLocaleString(DateUtil.getCurrentTime(), DateUtil.YYYY_MM_DD_HH_DD_SS));

                dto.setCitizenProperty(citizenPropertyDTO);
            }
            dto.getCitizenProperty().setCitizenInfoId(entity.getCitizenInfoId());
            citizenPropertyManager.save(dto.getCitizenProperty());
            //保存居民银行卡信息
            citizenBankManager.saveList(entity.getCitizenInfoId(), dto.getCitizenBankList());


        }

        return get(entity.getCitizenInfoId());
    }

    //删除单个居民信息
    public Boolean delete(Integer citizenInfoId) {
        CitizenInfo entity = citizenInfoMapperExt.selectByPrimaryKey(citizenInfoId);
        entity.setIsDelete(true);
        entity.setModifyTime(DateUtil.getCurrentTime());

        //级联删除相关表
        //待完善
        //删除citizen_property
        CitizenPropertyDTO citizenPropertyDTO = citizenPropertyManager.getByCitizenInfoId(entity.getCitizenInfoId());
        citizenPropertyDTO.setIsDelete(true);
        citizenPropertyManager.save(citizenPropertyDTO);

        //删除银行卡
        citizenBankManager.deleteByCitizenInfoId(citizenInfoId);

        //级联删除end

        return citizenInfoMapperExt.updateByPrimaryKeySelective(entity) > 0;
    }

    //分页查询居民信息列表
    public Pagination<CitizenInfoDTO> list(CitizenInfoSearchDTO citizenInfoSearchDTO) {
        Pagination<CitizenInfoDTO> result = new Pagination<CitizenInfoDTO>(citizenInfoSearchDTO.getCurrentPage(), citizenInfoSearchDTO.getPerPage());

        //如果HouseholdRegisterNumber不为空，则先查到对应的householdId
        if (StringUtils.isNotBlank(citizenInfoSearchDTO.getHouseholdRegisterNumber())) {
            HouseholdExample householdExample = new HouseholdExample();
            HouseholdExample.Criteria householdCriteria = householdExample.createCriteria();
            householdCriteria.andHouseholdRegisterNumberEqualTo(citizenInfoSearchDTO.getHouseholdRegisterNumber());
            householdCriteria.andIsDeleteEqualTo(false);
            List<Household> householdList = householdMapperExt.selectByExample(householdExample);
            if (householdList != null && householdList.size() > 0) {
                citizenInfoSearchDTO.setHouseholdId(householdList.get(0).getHouseholdId());
            }
        }


        CitizenInfoExample example = buildSearchExample(citizenInfoSearchDTO);
        int total = citizenInfoMapperExt.countByExample(example);
        result.setTotalCount(total);
        if (total > 0) {
            List<CitizenInfoDTO> data = new ArrayList<CitizenInfoDTO>();
            List<CitizenInfo> list = citizenInfoMapperExt.selectByExampleWithPaging(example, result.getOffset(), result.getPageSize());
            for (CitizenInfo entity : list) {
                CitizenInfoDTO dto = CitizenInfoDomainConvertUtils.convert(entity);

                dto.setAreaName(areaMapperExt.selectByPrimaryKey(dto.getAreaId()).getAreaName());

                try {
                    dto.setHouseholdRegisterNumber(householdMapperExt.selectByPrimaryKey(entity.getHouseholdId()).getHouseholdRegisterNumber());
                } catch (Exception ex) {
                    logger.info(ex.getMessage());
                }
                data.add(dto);
            }
            result.setList(data);
        }
        return result;
    }

    //导出人员信息记录
    public List<CitizenInfoDTO> downCitizen(CitizenInfoSearchDTO citizenInfoSearchDTO) {
        CitizenInfoExample example = buildSearchExample(citizenInfoSearchDTO);
        int total = citizenInfoMapperExt.countByExample(example);
        Vector<Thread> threads = new Vector<Thread>();
        LinkedBlockingQueue<CitizenInfoDTO> data = new LinkedBlockingQueue<CitizenInfoDTO>();
        LinkedBlockingQueue<CitizenInfoDTO> queue = new LinkedBlockingQueue<>();
        if (total > 0) {
            List<CitizenInfo> list = citizenInfoMapperExt.selectByExample(example);

            for (CitizenInfo entity : list) {
                CitizenInfoDTO dto = CitizenInfoDomainConvertUtils.convert(entity);
                try {
                    queue.put(dto);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }


            class DownCitizenThread implements Runnable {

                @Override
                public void run() {
                    try {
                        while (!queue.isEmpty()) {
                            CitizenInfoDTO d = queue.take();
                            d = getCitizenDTOForDown(d);
                            data.put(d);
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } finally {
                        logger.info("DownCitizenThread-finish queue.size():" + queue.size());
                    }
                }
            }

            int number = 0;
            while (number < CommonConstant.THREAD_NUMBER_UPLOAD_CITIZEN) {
                if (queue.size() < CommonConstant.THREAD_MAX_RECORD_COUNT) {
                    number = CommonConstant.THREAD_NUMBER_UPLOAD_CITIZEN;
                }
                number++;
                String threadName = "DownCitizenThread-" + Long.valueOf(System.currentTimeMillis()) + "-" + number;

                DownCitizenThread citizenUploadThread = new DownCitizenThread();

                Thread thread = new Thread(citizenUploadThread, threadName);
                threads.add(thread);
                thread.start();
            }

            for (Thread iThread : threads) {
                try {
                    //等待所有线程执行完毕
                    iThread.join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

        //
        logger.info("子线程均执行完毕");

        List<CitizenInfoDTO> result = new ArrayList<>();

        /*while (data.size() < total) {

            logger.info("sleep 1s");
            *//*try {
                Thread.sleep(1000L);
                logger.info("sleep 1s");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }*//*
        }*/
        while (!data.isEmpty()) {
            try {
                result.add(data.take());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        queue.clear();
        data.clear();

        return result;
    }

    public CitizenInfoDTO getCitizenDTOForDown(CitizenInfoDTO dto) {

        DictionaryDTO dic;

        try {

            //民族
            try {
                if (StringUtils.isNotBlank(dto.getNationCode())) {
                    dic = (DictionaryDTO) cacheService.getCache(String.format(CommonConstant.KEY_DIC, CommonConstant.DIC_TYPE_NATION, dto.getNationCode()));
                    dto.setNationName(dic.getDictionaryName());
                }
            } catch (Exception ex) {
                dto.setNationName("未知");
            }
            //学历
            try {
                if (StringUtils.isNotBlank(dto.getDegreeCode())) {
                    dic = (DictionaryDTO) cacheService.getCache(String.format(CommonConstant.KEY_DIC, CommonConstant.DIC_TYPE_DEGREE, dto.getDegreeCode()));
                    dto.setDegreeName(dic.getDictionaryName());
                }
            } catch (Exception ex) {
                dto.setDegreeName("未知");
            }
            //证件类型
            if (StringUtils.isNotBlank(dto.getIdentTypeCode())) {
                dic = (DictionaryDTO) cacheService.getCache(String.format(CommonConstant.KEY_DIC, CommonConstant.DIC_TYPE_IDENT, dto.getIdentTypeCode()));
                dto.setIdentTypeName(dic.getDictionaryName());
            }
            //开户银行名称
            List<CitizenBankDTO> bankDTOList = citizenBankManager.getByCitizenInfoId(dto.getCitizenInfoId());
            if (bankDTOList != null && bankDTOList.size() > 0) {
                CitizenBankDTO bankDTO = bankDTOList.get(0);
                if (StringUtils.isNotBlank(bankDTO.getBankCode())) {
                    dic = (DictionaryDTO) cacheService.getCache(String.format(CommonConstant.KEY_DIC, CommonConstant.DIC_TYPE_BANKCODE, bankDTO.getBankCode()));
                    dto.setBankCode(bankDTO.getBankCode());
                    dto.setBankName(dic.getDictionaryName());
                    dto.setBankNumber(bankDTO.getBankNumber());
                }
            }

            //用户所属行政区划
            Area area = (Area) cacheService.getCache(String.format(CommonConstant.KEY_AREA_DATA, dto.getAreaId()));
            dto.setAreaName(area.getAreaName());

            //户口簿编号，
            if (dto.getHouseholdId() != null && dto.getHouseholdId() > 0) {
                Household household = householdMapperExt.selectByPrimaryKey(dto.getHouseholdId());
                dto.setHouseholdRegisterNumber(household.getHouseholdRegisterNumber());
                dto.setHouseholdNumber(household.getHouseholdNumber());
            }

            //与户主关系
            try {
                if (StringUtils.isNotBlank(dto.getRelationCode())) {
                    dic = (DictionaryDTO) cacheService.getCache(String.format(CommonConstant.KEY_DIC, CommonConstant.DIC_TYPE_RELATION, dto.getRelationCode()));
                    dto.setRelationName(dic.getDictionaryName());
                }
            } catch (Exception ex) {
                dto.setRelationName("未知");
            }

            //人员分类
            try {
                if (StringUtils.isNotBlank(dto.getCitizenInfoTypeCode())) {
                    dic = (DictionaryDTO) cacheService.getCache(String.format(CommonConstant.KEY_DIC, CommonConstant.DIC_TYPE_CITIZEN_TYPECODE, dto.getCitizenInfoTypeCode()));
                    dto.setCitizenInfoTypeName(dic.getDictionaryName());
                }
            } catch (Exception ex) {
                dto.setCitizenInfoTypeName("未知");
            }

            //户口类型
            try {
                if (StringUtils.isNotBlank(dto.getHouseHoldTypeCode())) {
                    dic = (DictionaryDTO) cacheService.getCache(String.format(CommonConstant.KEY_DIC, CommonConstant.DIC_TYPE_TYPECODE_HOUSEHOLD, dto.getHouseHoldTypeCode()));
                    dto.setHouseHoldTypeName(dic.getDictionaryName());
                }
            } catch (Exception ex) {
                dto.setHouseHoldTypeName("未知");
            }
        } catch (Exception ex) {

        }

        return dto;
    }

    /**
     * 根据指定条件查询所有的citizeninfo
     *
     * @param citizenInfoSearchDTO
     * @return
     */
    public List<CitizenInfoDTO> getCitizenInfoList(CitizenInfoSearchDTO citizenInfoSearchDTO) {
        //build condition
        CitizenInfoExample example = new CitizenInfoExample();
        CitizenInfoExample.Criteria criteria = example.createCriteria();
        if (citizenInfoSearchDTO.getAll() != null && citizenInfoSearchDTO.getAll()) {
            if (citizenInfoSearchDTO.getAreaId() != null && citizenInfoSearchDTO.getAreaId() > 0) {
                criteria.andAreaIdEqualTo(citizenInfoSearchDTO.getAreaId());
            }
        } else {
            if (StringUtils.isNotBlank(citizenInfoSearchDTO.getName())) {
                criteria.andNameEqualTo(citizenInfoSearchDTO.getName());
            }
            if (citizenInfoSearchDTO.getAreaId() != null && citizenInfoSearchDTO.getAreaId() > 0) {
                criteria.andAreaIdEqualTo(citizenInfoSearchDTO.getAreaId());
            }
            if (StringUtils.isNotBlank(citizenInfoSearchDTO.getIdentNumber())) {
                criteria.andIdentNumberEqualTo(citizenInfoSearchDTO.getIdentNumber());
            }
            if (citizenInfoSearchDTO.getMaster() != null) {
                criteria.andIsMasterEqualTo(citizenInfoSearchDTO.getMaster());
            }
            if (citizenInfoSearchDTO.getCitizenInfoIds() != null && citizenInfoSearchDTO.getCitizenInfoIds().size() > 0) {
                criteria.andCitizenInfoIdIn(citizenInfoSearchDTO.getCitizenInfoIds());
            }
        }
        criteria.andIsDeleteEqualTo(Boolean.FALSE);
        List<CitizenInfo> citizenInfoList = citizenInfoMapperExt.selectByExample(example);
        List<CitizenInfoDTO> data = new ArrayList<CitizenInfoDTO>();
        for (CitizenInfo entity : citizenInfoList) {
            CitizenInfoDTO dto = CitizenInfoDomainConvertUtils.convert(entity);

            dto.setAreaName(areaMapperExt.selectByPrimaryKey(entity.getAreaId()).getAreaName());
//            (entity.getGenderCode().equals("100") ? "男" : "女");

            data.add(dto);
        }
        return data;
    }

    /**
     * 查询指定identNumber和非name的citizen
     *
     * @param identNumber
     * @param name
     * @return
     */
    public List<CitizenInfoDTO> getCitizenInfoListByNumber(String identNumber, String name) {
        //build condition
        CitizenInfoExample example = new CitizenInfoExample();
        CitizenInfoExample.Criteria criteria = example.createCriteria();

        //身份证号一致
        if (StringUtils.isNotBlank(identNumber)) {
            criteria.andIdentNumberEqualTo(identNumber);
        }
        //姓名不一致
        if (StringUtils.isNotBlank(name)) {
            criteria.andNameNotEqualTo(name);
        }
        criteria.andIsDeleteEqualTo(Boolean.FALSE);
        List<CitizenInfo> citizenInfoList = citizenInfoMapperExt.selectByExample(example);
        List<CitizenInfoDTO> data = new ArrayList<CitizenInfoDTO>();
        if (citizenInfoList != null) {
            for (CitizenInfo entity : citizenInfoList) {
                CitizenInfoDTO dto = CitizenInfoDomainConvertUtils.convert(entity);
                dto.setAreaName(areaMapperExt.selectByPrimaryKey(entity.getAreaId()).getAreaName());
                data.add(dto);
            }
        }
        return data;
    }

    public List<CitizenInfoDTO> getCitizenInfoIdListByNumber(String identNumber, String name) {
        //build condition
        CitizenInfoExample example = new CitizenInfoExample();
        CitizenInfoExample.Criteria criteria = example.createCriteria();
        if (StringUtils.isNotBlank(identNumber)) {
            criteria.andIdentNumberEqualTo(identNumber);
        }
        if (StringUtils.isNotBlank(name)) {
            criteria.andNameEqualTo(name);
        }
        criteria.andIsDeleteEqualTo(Boolean.FALSE);
        List<CitizenInfo> citizenInfoList = citizenInfoMapperExt.selectByExample(example);
        List<CitizenInfoDTO> data = new ArrayList<CitizenInfoDTO>();
        if (citizenInfoList != null) {
            for (CitizenInfo entity : citizenInfoList) {
                CitizenInfoDTO dto = CitizenInfoDomainConvertUtils.convert(entity);
                dto.setAreaName(areaMapperExt.selectByPrimaryKey(entity.getAreaId()).getAreaName());
                data.add(dto);
            }
        }
        return data;
    }

    //build查询Example
    public CitizenInfoExample buildSearchExample(CitizenInfoSearchDTO search) {
        CitizenInfoExample example = new CitizenInfoExample();
        CitizenInfoExample.Criteria criteria = example.createCriteria();

        if (search.getCitizenInfoId() != null && search.getCitizenInfoId() > 0) {
            criteria.andCitizenInfoIdEqualTo(search.getCitizenInfoId());
        }
        if (search.getAreaId() != null && search.getAreaId() > 0) {

            //查询该区划下所有的人员信息

            /*List<Integer> areaIds = areaManager.getChildrenAreaIds(search.getAreaId());
            areaIds.add(search.getAreaId());
            criteria.andAreaIdIn(areaIds);*/

            List<Integer> ids = (List<Integer>) cacheService.getCache(String.format(CommonConstant.KEY_AREA, search.getAreaId()));

            if (ids != null && ids.size() > 0) {
                ids.add(search.getAreaId());
                criteria.andAreaIdIn(ids);
            } else {
                criteria.andAreaIdEqualTo(search.getAreaId());
            }

//            criteria.andAreaIdEqualTo(search.getAreaId());
        }
        if (search.getHouseholdId() != null && search.getHouseholdId() > 0) {
            criteria.andHouseholdIdEqualTo(search.getHouseholdId());
        }
        if (search.getMaster() != null) {
            criteria.andIsMasterEqualTo(search.getMaster());
        }
        if (StringUtils.isNotBlank(search.getIdentNumber())) {
            criteria.andIdentNumberLike(search.getIdentNumber());
        }
        if (StringUtils.isNotBlank(search.getName())) {
            criteria.andNameLike(search.getName());
        }
        if (StringUtils.isNotBlank(search.getBirthdayBegin())) {
            criteria.andBirthdayGreaterThanOrEqualTo(DateUtil.parse(search.getBirthdayBegin(), DateUtil.DEFAULT_DATE_FORMAT));
        }
        if (StringUtils.isNotBlank(search.getBirthdayEnd())) {
            criteria.andBirthdayLessThanOrEqualTo(DateUtil.parse(search.getBirthdayEnd(), DateUtil.DEFAULT_DATE_FORMAT));
        }

        criteria.andIsDeleteEqualTo(Boolean.FALSE);
        if (StringUtils.isNotBlank(search.getOrderByClause())) {
            example.setOrderByClause(search.getOrderByClause());
        } else {
            example.setOrderByClause("citizen_info_id asc");
        }
        return example;
    }


    public Map<String, Object> validateAndUpdate(CitizenInfoDTO citizenInfoDTO, String batchId) {
        Map<String, Object> map = new HashMap<String, Object>();

        /*//检查各个必填字段是否都已经填写
        Map<String, Object> result = checkNullProperties(citizenInfoDTO);
        int checkNullResult = (int) result.get("code");
        if (checkNullResult != CitizenValidatingTypeEn.success.getCode().intValue()) {
            saveCitizenFail(citizenInfoDTO, (String) result.get("mean"), batchId);
            return result;
        }*/


        StringBuilder sb = new StringBuilder();

        //*********校验非空

        String f = checkNullProperties(citizenInfoDTO);

        //如果有校验不通过的规则，则需要写入失败表
        if (StringUtils.isNotBlank(f)) {
            saveCitizenFail(citizenInfoDTO, f, batchId);
            map.put("code", CitizenValidatingTypeEn.idCardFormatError.getCode());
            return map;
        }


        HouseholdDTO householdDTO = new HouseholdDTO();
        householdDTO.setHouseholdRegisterNumber(citizenInfoDTO.getHouseholdRegisterNumber());
        householdDTO.setHouseholdNumber(citizenInfoDTO.getHouseholdNumber());

        citizenInfoDTO.setHousehold(householdDTO);


        try {
            save(citizenInfoDTO, citizenInfoDTO.isNeedCheckIdCard());
            map.put("code", CitizenValidatingTypeEn.success.getCode());
        } catch (BusinessException ex) {
            //保存失败写入失败表，
            String failReason = ex.getMessage();
            saveCitizenFail(citizenInfoDTO, failReason, batchId);
            map.put("code", CitizenValidatingTypeEn.saveCitizenFail.getCode());
            map.put("mean", failReason);
        }

        return map;
    }

    /**
     * 写入失败表
     *
     * @param citizenInfoDTO
     * @param failReason
     * @return
     */
    private CitizenFailDTO saveCitizenFail(CitizenInfoDTO dto, String failReason, String batchId) {
        CitizenFailDTO record = new CitizenFailDTO();

        record.setName(dto.getName());
        record.setNameZw(dto.getNameZw());
        record.setNationName(dto.getNationName());
        record.setDegreeName(dto.getDegreeName());
        record.setIdentTypeName(dto.getIdentTypeName());
        record.setIdentNumber(dto.getIdentNumber());
        record.setBankName(dto.getCitizenBankList().get(0).getBankName());
        record.setBankNumber(dto.getCitizenBankList().get(0).getBankNumber());
        record.setAreaName(dto.getAreaName());
        record.setHouseholdRegisterNumber(dto.getHouseholdRegisterNumber());
        record.setMaster(dto.getMaster());
        record.setRelationName(dto.getRelationName());
        record.setHouseholdNumber(dto.getHouseholdNumber());
        record.setCitizenInfoTypeName(dto.getCitizenInfoTypeName());
        record.setHouseHoldTypeName(dto.getHouseHoldTypeName());
        record.setAddress(dto.getAddress());
        record.setAddressZw(dto.getAddressZw());
        record.setTelephone(dto.getTelephone());


//        record.setAreaId(dto.getAreaId());

        record.setBatchId(batchId);
        record.setFailReason(failReason);
        record.setFileUrl(null);
        //record.setGenderCode(dto.getGenderCode());

        if (UserUtils.getUser() != null) {
            record.setCreatorAreaId(UserUtils.getUser().getAreaId());
            record.setCreator(UserUtils.getUser().getUserName());
        }

        return citizenFailManager.save(record);
    }

    /**
     * get dictionary id
     *
     * @param dicTypeId
     * @param value
     * @return
     */
    public String getDicCodeByTypeAndValue(Integer dicTypeId, String value) {


        //查本地变量
        List<DictionaryDTO> list;

        if (ComUtils.dicMap != null && ComUtils.dicMap.size() > 0) {
            list = ComUtils.dicMap.get(dicTypeId);
            if (list != null && list.size() > 0)
                for (DictionaryDTO dictionaryDTO : list) {
                    if (dictionaryDTO.getDictionaryName().equals(value)) return dictionaryDTO.getDictionaryCode();
                }
        }
        //查redis

        list = (List<DictionaryDTO>) cacheService.getCache(String.format(CommonConstant.KEY_DIC_TYPE, dicTypeId));
        for (DictionaryDTO dictionaryDTO : list) {
            if (dictionaryDTO.getDictionaryName().equals(value)) return dictionaryDTO.getDictionaryCode();
        }


        //查数据库

        DictionarySearchDTO dictionarySearchDTO = new DictionarySearchDTO();
        dictionarySearchDTO.setDicTypeId(dicTypeId);
        dictionarySearchDTO.setDictionaryName(value);
        list = dictionaryManager.all(dictionarySearchDTO);
        if (list != null && list.size() > 0) {
            return list.get(0).getDictionaryCode();
        }


        return null;
    }

    /**
     * 检查非空属性
     *
     * @param dto
     * @return
     */
    private String checkNullProperties(CitizenInfoDTO dto) {

        StringBuilder sb = new StringBuilder();
        int index = 0;
        //姓名
        if (StringUtils.isBlank(dto.getName())) {
            String failReason = String.format(CitizenValidatingTypeEn.emptyField.getMean(), XlsHeaderConstant.CITIZEN_XLS_HEADERS[index]);
            sb.append(ComUtils.getFailReasonWithBlank(failReason + ";"));
        } else {
            if (dto.getName().contains(" ")) {
                String failReason = String.format(CitizenValidatingTypeEn.notAllowBlankErrorForField.getMean(), XlsHeaderConstant.CITIZEN_XLS_HEADERS[index]);
                sb.append(ComUtils.getFailReasonWithBlank(failReason + ";"));
            }
        }

        //民族*
        index = 2;
        if (StringUtils.isBlank(dto.getNationName())) {
            String failReason = String.format(CitizenValidatingTypeEn.emptyField.getMean(), XlsHeaderConstant.CITIZEN_XLS_HEADERS[index]);
            sb.append(ComUtils.getFailReasonWithBlank(failReason + ";"));
        } else {
            //民族
            String nationCode = getDicCodeByTypeAndValue(CommonConstant.DIC_TYPE_NATION, dto.getNationName());
            if (StringUtils.isBlank(nationCode)) {
                String failReason = String.format(CitizenValidatingTypeEn.dicCodeIsNull.getMean(), dto.getNationName());
                sb.append(ComUtils.getFailReasonWithBlank(failReason + ";"));
            /*saveCitizenFail(citizenInfoDTO, failReason, batchId);
            map.put("code", CitizenValidatingTypeEn.dicCodeIsNull.getCode());
            map.put("mean", failReason);
            return map;*/
            } else {
                dto.setNationCode(nationCode);
            }
        }

        //学历*
        index = 3;
        if (StringUtils.isBlank(dto.getDegreeName())) {
            String failReason = String.format(CitizenValidatingTypeEn.emptyField.getMean(), XlsHeaderConstant.CITIZEN_XLS_HEADERS[index]);
            sb.append(ComUtils.getFailReasonWithBlank(failReason + ";"));
        } else {
            //学历
            String degreeCode = getDicCodeByTypeAndValue(CommonConstant.DIC_TYPE_DEGREE, dto.getDegreeName());
            if (StringUtils.isBlank(degreeCode)) {
                String failReason = String.format(CitizenValidatingTypeEn.dicCodeIsNull.getMean(), dto.getDegreeName());
                sb.append(ComUtils.getFailReasonWithBlank(failReason + ";"));
            /*saveCitizenFail(citizenInfoDTO, failReason, batchId);
            map.put("code", CitizenValidatingTypeEn.dicCodeIsNull.getCode());
            map.put("mean", failReason);
            return map;*/
            } else {
                dto.setDegreeCode(degreeCode);
            }
        }

        //证件类型*
        index = 4;
        if (StringUtils.isBlank(dto.getIdentTypeName())) {
            String failReason = String.format(CitizenValidatingTypeEn.emptyField.getMean(), XlsHeaderConstant.CITIZEN_XLS_HEADERS[index]);
            sb.append(ComUtils.getFailReasonWithBlank(failReason + ";"));
        } else {
            //证件类型
            String identTypeCode = getDicCodeByTypeAndValue(CommonConstant.DIC_TYPE_IDENT, dto.getIdentTypeName());
            if (StringUtils.isBlank(identTypeCode)) {
                String failReason = String.format(CitizenValidatingTypeEn.dicCodeIsNull.getMean(), dto.getIdentTypeName());
                sb.append(ComUtils.getFailReasonWithBlank(failReason + ";"));
            /*saveCitizenFail(citizenInfoDTO, failReason, batchId);
            map.put("code", CitizenValidatingTypeEn.dicCodeIsNull.getCode());
            map.put("mean", failReason);
            return map;*/
            } else {
                dto.setIdentTypeCode(identTypeCode);
            }
        }

        //证件号码*
        index = 5;
        if (StringUtils.isBlank(dto.getIdentNumber())) {
            String failReason = String.format(CitizenValidatingTypeEn.emptyField.getMean(), XlsHeaderConstant.CITIZEN_XLS_HEADERS[index]);
            sb.append(ComUtils.getFailReasonWithBlank(failReason + ";"));
        } else {
            //检查身份证格式
            CheckIdCard cic = new CheckIdCard(dto.getIdentNumber());
            if (!cic.checkLength()) {
                //校验身份长度是是否是15位or18位
                String failReason = CitizenValidatingTypeEn.idCardLengthError.getMean();
                sb.append(ComUtils.getFailReasonWithBlank(failReason + ";"));
            /*saveCitizenFail(citizenInfoDTO, failReason, batchId);
            map.put("code", CitizenValidatingTypeEn.idCardLengthError.getCode());
            map.put("mean", failReason);
            return map;*/
            } else {

                if (dto.isNeedCheckIdCard()) {
                    if (!cic.validate()) {
                        String failReason = CitizenValidatingTypeEn.idCardFormatError.getMean();
                        sb.append(ComUtils.getFailReasonWithBlank(failReason + ";"));
                    }
                }

                /*if (!cic.validate()) {
                    String failReason = CitizenValidatingTypeEn.idCardFormatError.getMean();
                    sb.append(ComUtils.getFailReasonWithBlank(failReason + ";"));
                } else {*/
                //检查身份证是否已经存在
                CitizenInfoDTO idCarCheckCI = checkExistAndReturnDTO(dto.getIdentNumber());
                if (idCarCheckCI != null) {

                    //身份证已经被其他人使用
                    String failReason = String.format(CitizenValidatingTypeEn.identNumberUsed.getMean(), idCarCheckCI.getName(), idCarCheckCI.getAreaName());
                    sb.append(ComUtils.getFailReasonWithBlank(failReason + ";"));

/*
                        if (idCarCheckCI.getName().equals(dto.getName())) {
                            //已经导入过该人
                            String failReason = CitizenValidatingTypeEn.identNumberExist.getMean();
                            sb.append(ComUtils.getFailReasonWithBlank(failReason + ";"));

                        } else {
                            //身份证已经被其他人使用
                            String failReason = String.format(CitizenValidatingTypeEn.identNumberUsed.getMean(), idCarCheckCI.getName(), idCarCheckCI.getAreaName());
                            sb.append(ComUtils.getFailReasonWithBlank(failReason + ";"));

                        }
                        */


                }
//                }

            }
        }

        //开户银行名称*
        index = 6;
        logger.info("************bankName:" + dto.getBankName());
        CitizenBankDTO bankDTO = dto.getCitizenBankList().get(0);

        if (StringUtils.isBlank(bankDTO.getBankName())) {
            String failReason = String.format(CitizenValidatingTypeEn.emptyField.getMean(), XlsHeaderConstant.CITIZEN_XLS_HEADERS[index]);
            sb.append(ComUtils.getFailReasonWithBlank(failReason + ";"));
        } else {
            String bankCode = getDicCodeByTypeAndValue(CommonConstant.DIC_TYPE_BANKCODE, bankDTO.getBankName());
            //银行字典数据是否存在
            if (StringUtils.isBlank(bankCode)) {
                String failReason = String.format(CitizenValidatingTypeEn.dicCodeIsNull.getMean(), bankDTO.getBankName());
                sb.append(ComUtils.getFailReasonWithBlank(failReason + ";"));

            } else {
                bankDTO.setBankCode(bankCode);
            }

        }


        //开户银行卡号*
        index = 7;
        if (StringUtils.isBlank(bankDTO.getBankNumber())) {
            String failReason = String.format(CitizenValidatingTypeEn.emptyField.getMean(), XlsHeaderConstant.CITIZEN_XLS_HEADERS[index]);
            sb.append(ComUtils.getFailReasonWithBlank(failReason + ";"));
        } else {
            if (!MathUtil.isInteger(bankDTO.getBankNumber())) {
                String failReason = String.format(CitizenValidatingTypeEn.formatError.getMean(), XlsHeaderConstant.CITIZEN_XLS_HEADERS[index]);
                sb.append(ComUtils.getFailReasonWithBlank(failReason + ";"));
            } else {
                //银行卡号是否被他人使用
                CitizenBankDTO bankDTO2 = citizenBankManager.getByNumber(bankDTO.getBankNumber());
                if (bankDTO2 != null) {
                    //获取银行名称
                    DictionaryDTO dictionaryDTO = (DictionaryDTO) cacheService.getCache(String.format(CommonConstant.KEY_DIC, CommonConstant.DIC_TYPE_BANKCODE, bankDTO2.getBankCode()));

                    CitizenInfoDTO ci = get(bankDTO2.getCitizenInfoId());

                    String failReason = String.format(CitizenValidatingTypeEn.bankNumberUsed2.getMean(),
                            dictionaryDTO.getDictionaryName(),
                            bankDTO2.getBankNumber(),
                            ci != null ? ci.getName() : "未知",
                            ci != null ? ci.getAreaName() : "未知"
                    );
                    sb.append(ComUtils.getFailReasonWithBlank(failReason + ";"));

                }
            }
        }

        dto.getCitizenBankList().get(0).setBankCode(bankDTO.getBankCode());

        //用户归属行政区划*
        index = 8;
        if (StringUtils.isBlank(dto.getAreaName())) {
            String failReason = String.format(CitizenValidatingTypeEn.emptyField.getMean(), XlsHeaderConstant.CITIZEN_XLS_HEADERS[index]);
            sb.append(ComUtils.getFailReasonWithBlank(failReason + ";"));
        } else {
            //检查区划是否存在
            AreaSearchDTO areaSearchDTO = new AreaSearchDTO();
            areaSearchDTO.setAreaName(dto.getAreaName());
            if (UserUtils.getUser() != null && !UserUtils.getUser().getUserRole().equals("00")) {
                areaSearchDTO.setAreaParentId(UserUtils.getUser().getAreaId());
            }
            List<AreaDTO> areaList = areaManager.all(areaSearchDTO);
            if (areaList != null && areaList.size() > 0) {
                dto.setAreaId(areaList.get(0).getAreaId());
            } else {
                //区划不存在
                String failReason = CitizenValidatingTypeEn.areaNotExists.getMean();
                sb.append(ComUtils.getFailReasonWithBlank(failReason + ";"));
            }
        }


        //户口簿编号*
        index = 9;
        if (StringUtils.isBlank(dto.getHouseholdRegisterNumber())) {
            String failReason = String.format(CitizenValidatingTypeEn.emptyField.getMean(), XlsHeaderConstant.CITIZEN_XLS_HEADERS[index]);
            sb.append(ComUtils.getFailReasonWithBlank(failReason + ";"));
        } else {
            //校验是否为数字+字母
            if (!MathUtil.isNumberAndChar(dto.getHouseholdRegisterNumber())) {
                String failReason = String.format(CitizenValidatingTypeEn.formatError.getMean(), XlsHeaderConstant.CITIZEN_XLS_HEADERS[index]);
                sb.append(ComUtils.getFailReasonWithBlank(failReason + ";"));
            }
        }

        //是否户主*
        index = 10;
        if (dto.getMaster() == null) {
            String failReason = String.format(CitizenValidatingTypeEn.emptyField.getMean(), XlsHeaderConstant.CITIZEN_XLS_HEADERS[index]);
            sb.append(ComUtils.getFailReasonWithBlank(failReason + ";"));
        }

        //与户主关系*
        index = 11;
        if (StringUtils.isBlank(dto.getRelationName())) {
            String failReason = String.format(CitizenValidatingTypeEn.emptyField.getMean(), XlsHeaderConstant.CITIZEN_XLS_HEADERS[index]);
            sb.append(ComUtils.getFailReasonWithBlank(failReason + ";"));
        } else {
            //与户主关系
            String relationCode = getDicCodeByTypeAndValue(CommonConstant.DIC_TYPE_RELATION, dto.getRelationName());
            if (StringUtils.isBlank(relationCode)) {
                String failReason = String.format(CitizenValidatingTypeEn.dicCodeIsNull.getMean(), dto.getRelationName());
                sb.append(ComUtils.getFailReasonWithBlank(failReason + ";"));
            /*saveCitizenFail(citizenInfoDTO, failReason, batchId);
            map.put("code", CitizenValidatingTypeEn.dicCodeIsNull.getCode());
            map.put("mean", failReason);
            return map;*/
            } else {
                dto.setRelationCode(relationCode);
            }
        }

        //户主证件号码*
        index = 12;
        if (StringUtils.isBlank(dto.getHouseholdNumber())) {
            String failReason = String.format(CitizenValidatingTypeEn.emptyField.getMean(), XlsHeaderConstant.CITIZEN_XLS_HEADERS[index]);
            sb.append(ComUtils.getFailReasonWithBlank(failReason + ";"));
        } else if (dto.getMaster() != null) {
            if (dto.getMaster()) {
                //是户主，则户主关系只能为“户主”
                if (!dto.getRelationName().equals("户主") || !dto.getHouseholdNumber().equals(dto.getIdentNumber())) {
                    String failReason = "人员信息记录为户主，则与户主关系只能为‘户主’ 且 户主证件号需和身份证号一致";
                    sb.append(ComUtils.getFailReasonWithBlank(failReason + ";"));
                }
            } else {
                //则户主关系只能为户主之外的，且户主证件号码与本人证件号码不能相同；
                if (dto.getRelationName().equals("户主") || dto.getHouseholdNumber().equals(dto.getIdentNumber())) {
                    String failReason = "人员信息记录不为户主，则与户主关系不能为‘户主’ 且 户主证件号不能和身份证号一致";
                    sb.append(ComUtils.getFailReasonWithBlank(failReason + ";"));
                }
            }
        }

        //人员分类*
        index = 13;
        if (StringUtils.isBlank(dto.getCitizenInfoTypeName())) {
            String failReason = String.format(CitizenValidatingTypeEn.emptyField.getMean(), XlsHeaderConstant.CITIZEN_XLS_HEADERS[index]);
            sb.append(ComUtils.getFailReasonWithBlank(failReason + ";"));
        } else {
            //人员分类
            String citizenInfoTypeCode = getDicCodeByTypeAndValue(CommonConstant.DIC_TYPE_CITIZEN_TYPECODE, dto.getCitizenInfoTypeName());
            if (StringUtils.isBlank(citizenInfoTypeCode)) {
                String failReason = String.format(CitizenValidatingTypeEn.dicCodeIsNull.getMean(), dto.getCitizenInfoTypeName());
                sb.append(ComUtils.getFailReasonWithBlank(failReason + ";"));
            /*saveCitizenFail(citizenInfoDTO, failReason, batchId);
            map.put("code", CitizenValidatingTypeEn.dicCodeIsNull.getCode());
            map.put("mean", failReason);
            return map;*/
            } else {
                dto.setCitizenInfoTypeCode(citizenInfoTypeCode);
            }
        }

        //户口类别
        if (StringUtils.isNotBlank(dto.getHouseHoldTypeName())) {
            String houseHoldTypeCode = getDicCodeByTypeAndValue(CommonConstant.DIC_TYPE_TYPECODE_HOUSEHOLD, dto.getHouseHoldTypeName());
            if (StringUtils.isBlank(houseHoldTypeCode)) {
                String failReason = String.format(CitizenValidatingTypeEn.dicCodeIsNull.getMean(), dto.getHouseHoldTypeName());
                sb.append(ComUtils.getFailReasonWithBlank(failReason + ";"));
            /*saveCitizenFail(citizenInfoDTO, failReason, batchId);
            map.put("code", CitizenValidatingTypeEn.dicCodeIsNull.getCode());
            map.put("mean", failReason);
            return map;*/
            } else {
                dto.setHouseHoldTypeCode(houseHoldTypeCode);
            }
        }


        //电话号码格式
        index = 17;
        if (StringUtils.isNotBlank(dto.getTelephone()) && !MathUtil.isInteger(dto.getTelephone())) {
            String failReason = String.format(CitizenValidatingTypeEn.formatError.getMean(), XlsHeaderConstant.CITIZEN_XLS_HEADERS[index]);
            sb.append(ComUtils.getFailReasonWithBlank(failReason + ";"));
        }

        return sb.toString();
    }


    public void checkCitizen(CitizenInfo dto) {
        try {
            StringBuilder sb = new StringBuilder();

            //校验姓名
            if (dto.getName().contains(" ")) {
                sb.append("姓名不能包含空格;");
            }

            //校验身份证
            //检查身份证格式
            CheckIdCard cic = new CheckIdCard(dto.getIdentNumber());
            boolean idIsRight = false;
            if (!cic.checkLength()) {
                sb.append("身份证长度错误;");
            } else {
                if (!cic.validate()) {
                    sb.append("身份证编码规则错误;");
                } else {
                    idIsRight = true;

                    //身份证格式正确，提取出生年月日 性别 年龄
                    //获取出生年月
                    dto.setBirthday(DateUtil.parse(DateUtil.toLocaleString(cic.getBirthDate()), DateUtil.DEFAULT_DATE_FORMAT));
                    //获取性别
                    dto.setGenderCode(cic.getGenderCode() == 1 ? "100" : "101");
                    //获取年龄
                    dto.setAge(cic.getAge());
                }
            }

            //校验ident_type_code
            if (StringUtils.isBlank(dto.getIdentTypeCode())) {
                sb.append("证件类型不能为空;");
            }

            //nation_code
            if (StringUtils.isBlank(dto.getNationCode())) {
                sb.append("民族不能为空;");
            }

           /* //degree_code
            if (StringUtils.isBlank(dto.getDegreeCode())) {
                sb.append("学历不能为空;");
            }*/

            //citizen_info_type_code
            if (StringUtils.isBlank(dto.getCitizenInfoTypeCode())) {
                sb.append("人员分类不能为空;");
            }

            //house_hold_type_code
            if (StringUtils.isBlank(dto.getHouseHoldTypeCode())) {
                sb.append("户口类型不能为空;");
            }

            //是否户主，与户主关系
            if (dto.getIsMaster()) {
                if (StringUtils.isBlank(dto.getRelationCode()) || !dto.getRelationCode().equals("555")) {
                    sb.append("是户主，但是与户主关系不是‘户主’;");
                }
            } else {
                if (StringUtils.isBlank(dto.getRelationCode()) || dto.getRelationCode().equals("555")) {
                    sb.append("与户主关系为空，或不是户主，但是关系为‘户主’;");
                }
            }

            if (StringUtils.isNotBlank(sb.toString())) {
                //有问题的，则把有问题的信息，填进备注
                dto.setRemark(sb.toString());
            } else {
                dto.setRemark("ok");
            }
            citizenInfoMapperExt.updateByPrimaryKey(dto);
        } catch (Exception ex) {

        }
    }

}
